package com.example.spring.jpa.ast.handle;


import com.example.spring.jpa.ast.*;
import com.example.spring.jpa.ast.operation.AstDichotomyOperation;
import com.example.spring.jpa.ast.operation.AstNoDichotomyOperation;

/**
 * @author: orange
 * @create: 2023-07-22 21:44
 * @description:
 */
public class NoDichotomyHandle extends AbstractOperationHandle {
    private boolean match = false;
    private final String[] operations = {
            PriorityOperation.IsNull$1.getOperation(),
            PriorityOperation.IsNull$2.getOperation(),
            PriorityOperation.IsNotNull.getOperation(),
    };
    private final MinorOperation[] minorOperations = MinorOperation.values();

    @Override
    public boolean isMatch() {
        return this.match;
    }

    @Override
    public final AstNode handle(String exp, int start) throws Exception {
        if (exp == null || exp.length() == 0) return null;
        int bracket = 0;
        for (int i = start; i < exp.length(); i++) {
            if (exp.charAt(i) == '(') bracket++;
            else if (exp.charAt(i) == ')') bracket--;
            if (bracket == 0) {
                String ope = indexOfOperation(exp, i);
                this.match = ope != null;
                if (this.match) {
                    AstNoDichotomyOperation noDichotomy = AstNoDichotomyOperation.getInstance(ope);
                    noDichotomy.setSentence(ope);
                    noDichotomy.setAstNode(new AstStatic(exp.substring(0, i).trim()));
                    AstDichotomyOperation dichotomy = doHandle(exp, i + 1);
                    if (dichotomy != null) {
                        dichotomy.setLeft(noDichotomy);
                        return dichotomy;
                    }
                    return noDichotomy;
                }
            }
        }
        return null;
    }

    private AstDichotomyOperation doHandle(String exp, int start) throws Exception {
        int bracket = 0;
        for (int i = start; i < exp.length(); i++) {
            if (exp.charAt(i) == '(') bracket++;
            else if (exp.charAt(i) == ')') bracket--;
            if (bracket == 0) {
                String opa = opFormEnum(exp.substring(i));
                if (opa != null) {
                    AstDichotomyOperation dichotomy = AstDichotomyOperation.getInstance(opa);
                    AstExpression astExpression = new AstExpression(exp.substring(i + opa.length()));
                    dichotomy.setRight(astExpression);
                    return dichotomy;
                }
            }
        }
        return null;
    }

    private String opFormEnum(String exp) {
        for (int i = 0; i < minorOperations.length; i++) {
            if (exp.indexOf(minorOperations[i].getOperation()) == 0) {
                return minorOperations[i].getOperation();
            }
        }
        return null;
    }

    @Override
    public String[] operations() {
        return this.operations;
    }

    @Override
    public int order() {
        return 1;
    }
}
